<?php
/**
 * Manages user accounts in relation to magazine subcriptions.
 */
class ShoppSE_Users
{
	/**
	 * Contains a reference to the Shopp Magazine object.
	 * 
	 * @var Shopp_Magazine
	 */
	protected $subengine;
	
	
	
	/**
	 * Hook into Shopp and WordPress to handle magazine subscriber
	 * access.
	 * 
	 * @param ShoppSE $magazine
	 * @return ShoppSE_Users
	 */
	public function __construct(ShoppSE $subengine)
	{
		$this->subengine = $subengine;
	}


	/**
	 * Evaluates the period of time that the subscription is valid for
	 * and records it as meta data.
	 * 
	 * Use of the DateTime class made available as of PHP 5.3 would be ideal
	 * but has been avoided for compatibility reasons.
	 *
	 * @param int $user
	 * @param string $timestamp
	 * @param Price $price (Shopp price object used to ascertain if it
	 *        was a subscription-type product)
	 */
	public function markup_user_record($user, $timestamp, $price)
	{
		// Base date will be either the purchase date or current subscription expiry
		$current = get_user_meta($user, 'shoppse_subscription_expiry', true);
		$base = !empty($current) ? strtotime($current) : time();
		$base = $current != false ? $current : time();

		// The price object ought to include a "Recurring" array
		if (!property_exists($price, 'recurring') or !is_array($price->recurring))
		{
			if (SHOPP_DEBUG) new ShoppError('Unexpected price structure. Subscription abandoned.', 
				false, SHOPP_DEBUG_ERR);
			return;
		}

		// Calculate the subscription length in seconds
		$s = 0;

		switch ($price->recurring['period'])
		{
			case 'd': $s = $price->recurring['interval'] * 86400; break;
			case 'w': $s = $price->recurring['interval'] * 604800; break;
			case 'm': $s = $price->recurring['interval'] * 2592000; break;
			case 'y': $s = $price->recurring['interval'] * 31536000; break;
		}

		// Form the expiry date
		$expiry = $base + $s;

		// Y2038 problem: detection and workaround (32bit systems)
		if ($base === false) 
			$expiry = mktime(12, 0, 0, 30, 12, 2037);

		// Convert the expiry back to regular timestamp format
		$expiry = date('Y-m-d H:i:s', $expiry);

		// Last but not least, update the meta record
		if (!update_user_meta($user, 'shoppse_subscription_expiry', $expiry) and SHOPP_DEBUG)
			new ShoppError("Database could not be updated. Subscription abandoned.", false, SHOPP_DEBUG_ERR);
	}


	/**
	 * Determines if the current logged in user has
	 * permission to view the page.
	 *
	 * @return bool
	 */
	public function is_subscribed()
	{
		// User must be logged in
		if (!is_user_logged_in()) return false;

		// Get the user object
		$user = wp_get_current_user();
		$sub = get_user_meta($user->ID, 'shoppse_subscription_expiry', true);
		
		// If the meta field is not set then return false
		if (empty($sub)) return false;

		// Otherwise we need to compare the date
		$now = time();
		$expiry = strtotime($sub);

		if ($expiry >= $now) return true;
		else 
		{
			new ShoppError("Post access for {$user->user_nicename} failed.", false, SHOPP_DEBUG_ERR);
			return false;
		}
	}
	
	
	/**
	 * Provides a list of all subscribing users (not merely those
	 * with the WordPress defined role of "subscriber"). Optional
	 * $to and $from variables can be specified for pagination
	 * purposes.
	 * 
	 * A numerically indexed array of stdClass objects (containing
	 * ID, user_login, user_email and meta_value 
	 * 
	 * @param int $from = 0
	 * @param int $to = 20
	 * @return array
	 */
	public function list_users($from = 0, $to = 20)
	{
		// Definitions
		global $wpdb;
		$users = $wpdb->users;
		$meta = $wpdb->usermeta;
		
		// Pagination safety
		$from = (int) $from;
		$to = (int) $to;
		
		if ($from < 0) $from = 0;
		if ($to < 1 or $to > 1000) $to = 20;
		
		// Build the query
		$query = <<<SQL
			SELECT $users.ID AS id, 
			       $users.user_login AS name, 
			       $users.user_email AS email, 
			       $meta.meta_value AS expiry
			FROM   $users
			JOIN   $meta ON $users.ID = $meta.user_id
			WHERE  $meta.meta_key = 'shoppse_subscription_expiry'
			LIMIT  $from, $to;
SQL;
		// Execute and return
		return $wpdb->get_results($query);
	}
}